blob: 04679342eef1cc27831800fd5b3c63dd5473fa28 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// app/admin/page.tsx
'use client'
import { useState } from 'react'
export default function AdminPage() {
const [isLoading, setIsLoading] = useState(false)
const [lastResult, setLastResult] = useState<string | null>(null)
const clearTestData = async () => {
const confirmation = window.confirm(
'⚠️ 정말로 모든 테스트 데이터를 삭제하시겠습니까?\n\n삭제될 데이터:\n- Forms\n- Form Metas\n- Form Entries\n- Tags\n\n이 작업은 되돌릴 수 없습니다!'
)
if (!confirmation) return
setIsLoading(true)
setLastResult(null)
try {
const response = await fetch('/api/admin/clear-test-data', {
method: 'DELETE',
})
const result = await response.json()
if (result.success) {
setLastResult(`✅ 성공: ${result.message}`)
console.log('Deleted counts:', result.deleted)
} else {
setLastResult(`❌ 실패: ${result.error}`)
console.error('Error details:', result.details)
}
} catch (error) {
setLastResult(`❌ 네트워크 오류: ${error}`)
console.error('Network error:', error)
} finally {
setIsLoading(false)
}
}
const checkApiStatus = async () => {
try {
const response = await fetch('/api/admin/clear-test-data')
const result = await response.json()
setLastResult(`ℹ️ API 상태: ${result.message}`)
} catch (error) {
setLastResult(`❌ API 체크 실패: ${error}`)
}
}
return (
<div className="min-h-screen bg-gray-50 py-8">
<div className="max-w-2xl mx-auto px-4">
<div className="bg-white rounded-lg shadow-md p-6">
{/* 헤더 */}
<div className="border-b pb-4 mb-6">
<h1 className="text-2xl font-bold text-gray-900">
🔧 개발 관리자 패널
</h1>
<p className="text-gray-600 mt-2">
테스트 데이터 관리 및 개발 도구
</p>
<div className="mt-2 inline-block bg-yellow-100 text-yellow-800 px-2 py-1 rounded text-sm">
Development Mode Only
</div>
</div>
{/* 테스트 데이터 삭제 섹션 */}
<div className="mb-8">
<h2 className="text-lg font-semibold mb-4 text-gray-800">
🗑️ 테스트 데이터 삭제
</h2>
<div className="bg-red-50 border border-red-200 rounded-md p-4 mb-4">
<h3 className="font-medium text-red-800 mb-2">삭제될 테이블:</h3>
<ul className="text-sm text-red-700 space-y-1">
<li>• forms (양식 정보)</li>
<li>• form_metas (양식 메타데이터)</li>
<li>• form_entries (양식 입력 데이터)</li>
<li>• tags (태그 정보)</li>
</ul>
</div>
<div className="flex gap-3">
<button
onClick={clearTestData}
disabled={isLoading}
className={`px-4 py-2 rounded-md font-medium transition-colors ${
isLoading
? 'bg-gray-300 text-gray-500 cursor-not-allowed'
: 'bg-red-600 text-white hover:bg-red-700'
}`}
>
{isLoading ? '삭제 중...' : '🗑️ 전체 데이터 삭제'}
</button>
<button
onClick={checkApiStatus}
disabled={isLoading}
className="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors"
>
🔍 API 상태 확인
</button>
</div>
</div>
{/* 결과 표시 */}
{lastResult && (
<div className="bg-gray-50 border rounded-md p-4">
<h3 className="font-medium text-gray-800 mb-2">실행 결과:</h3>
<p className="text-sm font-mono whitespace-pre-wrap">
{lastResult}
</p>
</div>
)}
{/* 추가 정보 */}
<div className="mt-8 pt-6 border-t">
<h3 className="font-medium text-gray-800 mb-2">📋 사용법:</h3>
<div className="text-sm text-gray-600 space-y-1">
<p>• 이 페이지는 개발 환경에서만 접근 가능합니다</p>
<p>• 삭제 전 반드시 확인 창이 표시됩니다</p>
<p>• API 엔드포인트: <code className="bg-gray-100 px-1 rounded">/api/admin/clear-test-data</code></p>
</div>
</div>
</div>
</div>
</div>
)
}
|